home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / util / gnu / gnu_oleo_1_2_2.lha / oleo-1.2.2 / lists.c < prev    next >
C/C++ Source or Header  |  1993-03-03  |  23KB  |  1,137 lines

  1. /*    Copyright (C) 1990, 1992, 1993 Free Software Foundation, Inc.
  2.  
  3. This file is part of Oleo, the GNU Spreadsheet.
  4.  
  5. Oleo is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2, or (at your option)
  8. any later version.
  9.  
  10. Oleo is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with Oleo; see the file COPYING.  If not, write to
  17. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. #include "funcdef.h"
  20.  
  21. #define obstack_chunk_alloc ck_malloc
  22. #define obstack_chunk_free free
  23. #include "obstack.h"
  24. #include "sysdef.h"
  25. #include "global.h"
  26. #include "cell.h"
  27. #include "ref.h"
  28. #include "window.h"
  29.  
  30. #define ROW_BUF 3
  31. #define COL_BUF 2
  32. #define MAX MAX_ROW
  33. #define MIN MIN_ROW
  34. static struct obstack find_stack;
  35.  
  36. #if 1
  37. #define malloc_chain_check(x)
  38. #endif
  39.  
  40. #ifdef __GNUC__
  41. #define inline __inline__
  42. #else
  43. #define inline
  44. #endif
  45.  
  46. #ifdef TEST_ME
  47. typedef unsigned char CELLREF;
  48. typedef unsigned int size_t;
  49. #define ck_malloc malloc
  50. extern void *malloc ();
  51. #define MIN 1
  52. #define MAX 65535
  53. #endif
  54.  
  55. struct list
  56.   {
  57.     CELLREF lo, hi;
  58.     struct list *next;
  59.     char mem[1];
  60.   };
  61.  
  62. struct find
  63.   {
  64.     struct find *next;
  65.     CELLREF lo, hi, cur;
  66.     struct list **start;
  67.     struct list *curptr;
  68.     CELLREF left;
  69.     void *ret;
  70.     char fini;
  71.     int ele;
  72.   };
  73.  
  74. struct find *finds;
  75.  
  76. static inline void
  77. flush (ptr)
  78.      struct list *ptr;
  79. {
  80.   struct list *nxt;
  81.  
  82.   while (ptr)
  83.     {
  84.       nxt = ptr->next;
  85.       free (ptr);
  86.       ptr = nxt;
  87.     }
  88. }
  89.  
  90. static inline void
  91. resync (tofree, new, ele)
  92.      struct list *tofree;
  93.      struct list *new;
  94.      int ele;
  95. {
  96.   extern struct cell *my_cell;
  97.   struct find *findp;
  98.  
  99.   if (ele == sizeof (struct cell) && my_cell && (char *) my_cell >= tofree->mem && (char *) my_cell <= tofree->mem + ele * (1 + tofree->hi - tofree->lo))
  100.       my_cell = (struct cell *) (new->mem + ele * (cur_row - new->lo));
  101.   for (findp = finds; findp; findp = findp->next)
  102.     {
  103.       if (tofree == findp->curptr)
  104.     {
  105.       CELLREF hi;
  106.       findp->curptr = new;
  107.       findp->ret = new->mem + (findp->cur - new->lo) * ele;
  108.       hi = (findp->hi < new->hi ? findp->hi : new->hi);
  109.       if (findp->cur < hi)
  110.         findp->left = hi - findp->cur;
  111.     }
  112.     }
  113.   free (tofree);
  114. }
  115.  
  116. static inline void *
  117. find (pos, ptr, ele)
  118.      CELLREF pos;
  119.      struct list *ptr;
  120.      int ele;
  121. {
  122.   for (; ptr; ptr = ptr->next)
  123.     {
  124.       if (ptr->lo > pos)
  125.     break;
  126.       if (ptr->hi >= pos)
  127.     return ptr->mem + (pos - ptr->lo) * ele;
  128.     }
  129.   return 0;
  130. }
  131.  
  132. static inline void *
  133. make (pos, prevp, ele, buf)
  134.      CELLREF pos;
  135.      struct list **prevp;
  136.      int ele;
  137.      int buf;
  138. {
  139.   CELLREF lo, hi;
  140.   size_t size;
  141.   struct list *ptr;
  142.  
  143.   while (*prevp && (*prevp)->next && (*prevp)->next->lo < pos)
  144.     prevp = &((*prevp)->next);
  145.  
  146.   /* Was it easy? */
  147.   if (*prevp && (*prevp)->lo <= pos && (*prevp)->hi >= pos)
  148.     return (*prevp)->mem + (pos - (*prevp)->lo) * ele;
  149.  
  150.   lo = (pos < MIN + buf) ? MIN : pos - buf;
  151.   hi = (pos > MAX - buf) ? MAX : pos + buf;
  152.  
  153.   if (!*prevp
  154.       || ((*prevp)->hi < lo - 1
  155.       && (!(*prevp)->next
  156.           || (*prevp)->next->lo - 1 > hi)))
  157.     {
  158.       /* Allocate a whole new structure */
  159.       size = (1 + hi - lo) * ele;
  160.       ptr = ck_malloc (sizeof (struct list) + size);
  161.       ptr->lo = lo;
  162.       ptr->hi = hi;
  163.       if (*prevp && (*prevp)->hi < lo)
  164.     {
  165.       ptr->next = (*prevp)->next;
  166.       (*prevp)->next = ptr;
  167.     }
  168.       else
  169.     {
  170.       ptr->next = *prevp;
  171.       *prevp = ptr;
  172.     }
  173.       bzero (ptr->mem, size);
  174.       malloc_chain_check (1);
  175.     }
  176.   else if ((*prevp)->lo > lo)
  177.     {
  178.       /* Stretch one down a bit to fit */
  179.       hi = (*prevp)->hi;
  180.       size = (1 + hi - lo) * ele;
  181.       ptr = ck_malloc (sizeof (struct list) + size);
  182.       ptr->lo = lo;
  183.       ptr->hi = hi;
  184.       ptr->next = (*prevp)->next;
  185.       bcopy ((*prevp)->mem, ptr->mem + ((*prevp)->lo - ptr->lo) * ele, (1 + (*prevp)->hi - (*prevp)->lo) * ele);
  186.       bzero (ptr->mem, ((*prevp)->lo - ptr->lo) * ele);
  187.       resync (*prevp, ptr, ele);
  188.       *prevp = ptr;
  189.       malloc_chain_check (1);
  190.     }
  191.   else if ((*prevp)->hi < hi && (*prevp)->next && (*prevp)->next->lo <= hi)
  192.     {
  193.       /* Merge this one and the one after it */
  194.       size = (1 + (*prevp)->next->hi - (*prevp)->lo) * ele;
  195.       ptr = ck_malloc (sizeof (struct list) + size);
  196.       ptr->lo = (*prevp)->lo;
  197.       ptr->hi = (*prevp)->next->hi;
  198.       ptr->next = (*prevp)->next->next;
  199.       bcopy ((*prevp)->mem, ptr->mem, (1 + (*prevp)->hi - (*prevp)->lo) * ele);
  200.       bzero (ptr->mem + (1 + (*prevp)->hi - ptr->lo) * ele, ((*prevp)->next->lo - (*prevp)->hi) * ele);
  201.       bcopy ((*prevp)->next->mem,
  202.          ptr->mem + ((*prevp)->next->lo - ptr->lo) * ele,
  203.          (1 + (*prevp)->next->hi - (*prevp)->next->lo) * ele);
  204.       resync ((*prevp)->next, ptr, ele);
  205.       resync (*prevp, ptr, ele);
  206.       *prevp = ptr;
  207.       malloc_chain_check (1);
  208.     }
  209.   else if ((*prevp)->hi < hi)
  210.     {
  211.       /* stretch this one up a bit */
  212.       size = (1 + hi - (*prevp)->lo) * ele;
  213.       ptr = ck_malloc (sizeof (struct list) + size);
  214.       ptr->lo = (*prevp)->lo;
  215.       ptr->hi = hi;
  216.       ptr->next = (*prevp)->next;
  217.       bcopy ((*prevp)->mem, ptr->mem, (1 + (*prevp)->hi - (*prevp)->lo) * ele);
  218.       bzero (ptr->mem + (1 + (*prevp)->hi - ptr->lo) * ele, (hi - (*prevp)->hi) * ele);
  219.       resync (*prevp, ptr, ele);
  220.       *prevp = ptr;
  221.       malloc_chain_check (1);
  222.     }
  223.   else
  224.     ptr = *prevp;
  225. #ifdef TEST
  226.   if (ptr->lo > pos || ptr->hi < pos)
  227.     panic ("Make at %u not in %u %u", pos, ptr->lo, ptr->hi);
  228. #endif
  229.  
  230.   return ptr->mem + (pos - ptr->lo) * ele;
  231. }
  232.  
  233. static inline void *
  234. find_rng (start, lo, hi, ele)
  235.      struct list **start;
  236.      CELLREF lo;
  237.      CELLREF hi;
  238.      int ele;
  239. {
  240.   struct list *ptr;
  241.   struct find *f;
  242.  
  243.   f = (struct find *)obstack_alloc (&find_stack, sizeof (struct find));
  244.   f->lo = lo;
  245.   f->hi = hi;
  246.   f->ele = ele;
  247.   f->start = start;
  248.   for (ptr = *start; ptr; ptr = ptr->next)
  249.     if (ptr->hi >= lo)
  250.       break;
  251.   if (ptr && ptr->lo <= hi)
  252.     {
  253.       f->cur = (ptr->lo > lo ? ptr->lo : lo);
  254.       f->curptr = ptr;
  255.       f->ret = ptr->mem + (f->cur - ptr->lo) * ele;
  256.       f->left = 1 + (f->hi < ptr->hi ? f->hi : ptr->hi) - f->cur;
  257.       f->fini = 0;
  258.     }
  259.   else
  260.     f->fini = 1;
  261.   f->next = finds;
  262.   finds = f;
  263.   return f;
  264. }
  265.  
  266. static inline void *
  267. make_rng (start, lo, hi, ele, buf)
  268.      struct list **start;
  269.      CELLREF lo;
  270.      CELLREF hi;
  271.      int ele;
  272.      int buf;
  273. {
  274.   struct list **prevp;
  275.   struct list *ptr;
  276.   size_t size;
  277.   struct find *f;
  278.  
  279.   f = (struct find *)obstack_alloc (&find_stack, sizeof (struct find));
  280.   f->lo = f->cur = lo;
  281.   f->hi = hi;
  282.   f->left = 1 + hi - lo;
  283.   f->fini = 0;
  284.   f->ele = ele;
  285.   f->start = start;
  286.  
  287.   lo = lo <= MIN + buf ? MIN : lo - buf;
  288.   hi = hi >= MAX - buf ? MAX : hi + buf;
  289.  
  290.   for (prevp = start; *prevp && (*prevp)->hi < lo - 1; prevp = &((*prevp)->next))
  291.     ;
  292.   ptr = *prevp;
  293.   if (!*prevp || (*prevp)->lo - 1 > hi)
  294.     {
  295.       /* Allocate the whole thing */
  296.       size = (1 + hi - lo) * ele;
  297.       ptr = ck_malloc (sizeof (struct list) + size);
  298.       ptr->lo = lo;
  299.       ptr->hi = hi;
  300.       ptr->next = *prevp;
  301.       bzero (ptr->mem, size);
  302.       if (*prevp && (*prevp)->hi < lo)
  303.     {
  304.       ptr->next = (*prevp)->next;
  305.       (*prevp)->next = ptr;
  306.     }
  307.       else
  308.     {
  309.       ptr->next = *prevp;
  310.       *prevp = ptr;
  311.     }
  312.       *prevp = ptr;
  313.       malloc_chain_check (1);
  314.     }
  315.   else
  316.     {
  317.       if ((*prevp)->lo > lo)
  318.     {
  319.       /* Stretch this one down a bit */
  320.       size = (1 + (*prevp)->hi - lo) * ele;
  321.       ptr = ck_malloc (sizeof (struct list) + size);
  322.       ptr->lo = lo;
  323.       ptr->hi = (*prevp)->hi;
  324.       ptr->next = (*prevp)->next;
  325.       bcopy ((*prevp)->mem,
  326.          ptr->mem + ((*prevp)->lo - ptr->lo) * ele,
  327.          (1 + (*prevp)->hi - (*prevp)->lo) * ele);
  328.       bzero (ptr->mem, ((*prevp)->lo - lo) * ele);
  329.       resync (*prevp, ptr, ele);
  330.       *prevp = ptr;
  331.       malloc_chain_check (1);
  332.     }
  333.       while ((*prevp)->hi < hi && (*prevp)->next && (*prevp)->next->lo <= hi)
  334.     {
  335.       /* Merge this one and the one after it */
  336.       /* Repeat as needed */
  337.       size = (1 + (*prevp)->next->hi - (*prevp)->lo) * ele;
  338.       ptr = ck_malloc (sizeof (struct list) + size);
  339.       ptr->lo = (*prevp)->lo;
  340.       ptr->hi = (*prevp)->next->hi;
  341.       ptr->next = (*prevp)->next->next;
  342.       bcopy ((*prevp)->mem, ptr->mem, (1 + (*prevp)->hi - (*prevp)->lo) * ele);
  343.       bzero (ptr->mem + (1 + (*prevp)->hi - ptr->lo) * ele, ((*prevp)->next->lo - (*prevp)->hi) * ele);
  344.       bcopy ((*prevp)->next->mem,
  345.          ptr->mem + ((*prevp)->next->lo - ptr->lo) * ele,
  346.          (1 + (*prevp)->next->hi - (*prevp)->next->lo) * ele);
  347.       resync ((*prevp)->next, ptr, ele);
  348.       resync (*prevp, ptr, ele);
  349.       *prevp = ptr;
  350.       malloc_chain_check (1);
  351.     }
  352.       if ((*prevp)->hi < hi)
  353.     {
  354.       /* stretch this one up a bit */
  355.       size = (1 + hi - (*prevp)->lo) * ele;
  356.       ptr = ck_malloc (sizeof (struct list) + size);
  357.       ptr->lo = (*prevp)->lo;
  358.       ptr->hi = hi;
  359.       ptr->next = (*prevp)->next;
  360.       bcopy ((*prevp)->mem, ptr->mem, (1 + (*prevp)->hi - (*prevp)->lo) * ele);
  361.       bzero (ptr->mem + (1 + (*prevp)->hi - ptr->lo) * ele, (hi - (*prevp)->hi) * ele);
  362.       resync (*prevp, ptr, ele);
  363.       *prevp = ptr;
  364.       malloc_chain_check (1);
  365.     }
  366.     }
  367. #ifdef TEST
  368.   if (ptr->lo > f->lo || ptr->hi < f->hi)
  369.     panic ("Vector of %u-%u not big enough for %u-%u", (*prevp)->lo, (*prevp)->hi, f->lo, f->hi);
  370. #endif
  371.   f->curptr = ptr;
  372.   f->ret = ptr->mem + (f->cur - ptr->lo) * ele;
  373.   f->next = finds;
  374.   finds = f;
  375.   return f;
  376. }
  377.  
  378. static inline void *
  379. next_rng (f, posp)
  380.      struct find *f;
  381.      CELLREF *posp;
  382. {
  383.   void *ret;
  384.   struct find *next;
  385.  
  386.   if (!f)
  387.     return 0;
  388.   if (!f->fini)
  389.     {
  390.       if (f->left)
  391.     {
  392.       --(f->left);
  393.     fini:
  394.       if (posp)
  395.         *posp = f->cur;
  396.       f->cur++;
  397.       ret = f->ret;
  398.       f->ret = (char *) (f->ret) + f->ele;
  399.       return ret;
  400.     }
  401.       if (f->curptr->hi < f->hi)
  402.     {
  403.       f->curptr = f->curptr->next;
  404.       if (f->curptr && f->curptr->lo <= f->hi)
  405.         {
  406.           f->ret = f->curptr->mem;
  407.           f->left = (f->hi < f->curptr->hi ? f->hi : f->curptr->hi) - f->curptr->lo;
  408.           f->cur = f->curptr->lo;
  409.           goto fini;
  410.         }
  411.     }
  412.     }
  413.   next = f->next;
  414.   obstack_free (&find_stack, f);
  415.   finds = next;
  416.   return 0;
  417. }
  418.  
  419.  
  420. struct cf
  421.   {
  422.     struct cf *next;
  423.     struct find *rows, *cols;
  424.     int make;
  425.   };
  426.  
  427. static struct cf *fp;
  428. static struct list *the_cols;
  429.  
  430. extern unsigned short default_width;
  431. static struct find *w_find;
  432.  
  433. extern unsigned short default_height;
  434. static struct find *h_find;
  435.  
  436. static struct list *wids, *hgts;
  437.  
  438. void 
  439. init_cells ()
  440. {
  441.   obstack_begin (&find_stack, sizeof (struct find) * 15);
  442.   the_cols = 0;
  443.   wids = 0;
  444.   hgts = 0;
  445. }
  446.  
  447. void 
  448. flush_everything ()
  449. {
  450.   struct list *ptr, *nxt;
  451.   int n;
  452.  
  453.   flush_variables ();
  454.   for (ptr = the_cols; ptr; ptr = nxt)
  455.     {
  456.       nxt = ptr->next;
  457.       for (n = 0; n <= ptr->hi - ptr->lo; n++)
  458.     flush (*(struct list **) (ptr->mem + (n * sizeof (struct list *))));
  459.       free (ptr);
  460.     }
  461.   the_cols = 0;
  462.   flush (wids);
  463.   wids = 0;
  464.   flush (hgts);
  465.   hgts = 0;
  466.   flush_fonts ();
  467. }
  468.  
  469. #if __STDC__
  470. struct cell *
  471. find_cell (CELLREF row, CELLREF col)
  472. #else
  473. struct cell *
  474. find_cell (row, col)
  475.      CELLREF row;
  476.      CELLREF col;
  477. #endif
  478. {
  479.   void **v;
  480.  
  481.   v = find (col, the_cols, sizeof (void *));
  482.   return v ? find (row, *v, sizeof (struct cell)) : 0;
  483. }
  484.  
  485. #if __STDC__
  486. struct cell *
  487. find_or_make_cell (CELLREF row, CELLREF col)
  488. #else
  489. struct cell *
  490. find_or_make_cell (row, col)
  491.      CELLREF row;
  492.      CELLREF col;
  493. #endif
  494. {
  495.   struct list **v;
  496.  
  497.   v = make (col, &the_cols, sizeof (struct list *), COL_BUF);
  498.   return make (row, v, sizeof (struct cell), ROW_BUF);
  499. }
  500.  
  501. void
  502. find_cells_in_range (r)
  503.      struct rng *r;
  504. {
  505.   struct cf *new;
  506.   struct list **firstcol;
  507.  
  508.   new = (struct cf *)obstack_alloc (&find_stack, sizeof (struct cf));
  509.   new->make = 0;
  510.   new->next = fp;
  511.   fp = new;
  512.   new->rows = find_rng (&the_cols, r->lc, r->hc, sizeof (void *));
  513.   firstcol = next_rng (new->rows, 0);
  514.   if (firstcol)
  515.     new->cols = find_rng (firstcol, r->lr, r->hr, sizeof (struct cell));
  516.   else
  517.     new->cols = 0;
  518. }
  519.  
  520. void
  521. make_cells_in_range (r)
  522.      struct rng *r;
  523. {
  524.   struct cf *new;
  525.   struct list **firstcol;
  526.  
  527.   new = (struct cf *)obstack_alloc (&find_stack, sizeof (struct cf));
  528.   new->make = 1;
  529.   new->next = fp;
  530.   fp = new;
  531.   new->rows = make_rng (&the_cols, r->lc, r->hc, sizeof (void *), ROW_BUF);
  532.   firstcol = next_rng (new->rows, 0);
  533.   new->cols = make_rng (firstcol, r->lr, r->hr, sizeof (struct cell), COL_BUF);
  534. }
  535.  
  536. struct cell *
  537. next_cell_in_range ()
  538. {
  539.   struct cell *ret;
  540.   void *new_row;
  541.  
  542.   for (;;)
  543.     {
  544.       if (ret = next_rng (fp->cols, 0))
  545.     return ret;
  546.       new_row = next_rng (fp->rows, 0);
  547.       if (!new_row)
  548.     {
  549.       struct cf *old;
  550.  
  551.       old = fp->next;
  552.       obstack_free (&find_stack, fp);
  553.       fp = old;
  554.       return 0;
  555.     }
  556.       fp->cols = fp->make ? make_rng (new_row, fp->cols->lo, fp->cols->hi, sizeof (struct cell), ROW_BUF)
  557.       : find_rng (new_row, fp->cols->lo, fp->cols->hi, sizeof (struct cell));
  558.     }
  559. }
  560.  
  561. struct cell *
  562. next_row_col_in_range (rowp, colp)
  563.      CELLREF *rowp;
  564.      CELLREF *colp;
  565. {
  566.   struct cell *ret;
  567.   struct list **new_row;
  568.  
  569.   for (;;)
  570.     {
  571.       if (ret = next_rng (fp->cols, rowp))
  572.     {
  573.       *colp = fp->rows->cur - 1;
  574.       return ret;
  575.     }
  576.       new_row = next_rng (fp->rows, colp);
  577.       if (!new_row)
  578.     {
  579.       struct cf *old;
  580.  
  581.       old = fp->next;
  582.       obstack_free (&find_stack, fp);
  583.       fp = old;
  584.       return 0;
  585.     }
  586.       fp->cols = fp->make ? make_rng (new_row, fp->cols->lo, fp->cols->hi, sizeof (struct cell), ROW_BUF)
  587.       : find_rng (new_row, fp->cols->lo, fp->cols->hi, sizeof (struct cell));
  588.     }
  589. }
  590.  
  591. void
  592. no_more_cells ()
  593. {
  594.   struct cf *old;
  595.  
  596.   old = fp->next;
  597.   obstack_free (&find_stack, fp);
  598.   fp = old;
  599. }
  600.  
  601. CELLREF
  602. max_row (col)
  603.      CELLREF col;
  604. {
  605.   struct list **ptr;
  606.  
  607.   ptr = find (col, the_cols, sizeof (void *));
  608.   if (!ptr || !*ptr)
  609.     return MIN;
  610.   while ((*ptr)->next)
  611.     ptr = &((*ptr)->next);
  612.   return (*ptr)->hi;
  613. }
  614.  
  615. CELLREF
  616. max_col (row)
  617.      CELLREF row;
  618. {
  619.   struct list *ptr;
  620.  
  621.   if (!the_cols)
  622.     return MIN;
  623.   for (ptr = the_cols; ptr->next; ptr = ptr->next)
  624.     ;
  625.   return ptr->hi;
  626. }
  627.  
  628. CELLREF 
  629. highest_row ()
  630. {
  631.   void *f;
  632.   struct list **ptr;
  633.   CELLREF hi = MIN;
  634.  
  635.   f = find_rng (&the_cols, MIN, MAX, sizeof (void *));
  636.   while (ptr = next_rng (f, 0))
  637.     {
  638.       if (*ptr)
  639.     {
  640.       while ((*ptr)->next)
  641.         ptr = &((*ptr)->next);
  642.       if ((*ptr)->hi > hi)
  643.         hi = (*ptr)->hi;
  644.     }
  645.     }
  646.   return hi;
  647. }
  648.  
  649.  
  650. CELLREF 
  651. highest_col ()
  652. {
  653.   struct list *ptr;
  654.  
  655.   if (!the_cols)
  656.     return MIN;
  657.   for (ptr = the_cols; ptr->next; ptr = ptr->next)
  658.     ;
  659.   return ptr->hi;
  660. }
  661.  
  662.  
  663. /* Routines for dealing with the widths of columns. . . */
  664.  
  665. #ifdef __STDC__
  666. unsigned short 
  667. get_width (CELLREF col)
  668. #else
  669. unsigned short 
  670. get_width (col)
  671.      CELLREF col;
  672. #endif
  673. {
  674.   unsigned short *ptr;
  675.  
  676.   ptr = find (col, wids, sizeof (unsigned short));
  677.   if (!ptr || !*ptr)
  678.     return default_width;
  679.   return (*ptr) - 1;
  680. }
  681.  
  682.  
  683. #ifdef __STDC__
  684. unsigned short 
  685. get_nodef_width (CELLREF col)
  686. #else
  687. unsigned short 
  688. get_nodef_width (col)
  689.      CELLREF col;
  690. #endif
  691. {
  692.   unsigned short *ptr;
  693.  
  694.   ptr = find (col, wids, sizeof (unsigned short));
  695.   return ptr ? *ptr : 0;
  696. }
  697.  
  698. void 
  699. set_width (col, wid)
  700.      CELLREF col;
  701.      unsigned short wid;
  702. {
  703.   unsigned short *ptr;
  704.  
  705.   ptr = make (col, &wids, sizeof (unsigned short), COL_BUF);
  706.   *ptr = wid;
  707. }
  708.  
  709. void 
  710. find_widths (lo, hi)
  711.      CELLREF lo;
  712.      CELLREF hi;
  713. {
  714.   w_find = find_rng (&wids, lo, hi, sizeof (unsigned short));
  715. }
  716.  
  717. unsigned short 
  718. next_width (posp)
  719.      CELLREF *posp;
  720. {
  721.   unsigned short *ptr;
  722.  
  723.   do
  724.     ptr = next_rng (w_find, posp);
  725.   while (ptr && !*ptr);
  726.   return ptr ? *ptr : 0;
  727. }
  728.  
  729. static void
  730. do_shift (over, lo, hi, start, buf)
  731.      int over;
  732.      CELLREF lo;
  733.      CELLREF hi;
  734.      struct list **start;
  735.      int buf;
  736. {
  737.   CELLREF pos;
  738.   unsigned short w;
  739.   unsigned short *ptr;
  740.   int inc;
  741.   struct list *p;
  742.  
  743.   if (!*start)
  744.     return;
  745.   for (p = *start; p->next; p = p->next)
  746.     ;
  747.   if (hi > p->hi)
  748.     hi = p->hi;
  749.  
  750.   if (over > 0)
  751.     {
  752.       pos = hi;
  753.       hi = lo;
  754.       lo = pos;
  755.       inc = -1;
  756.     }
  757.   else
  758.     inc = 1;
  759.  
  760.   for (pos = lo;; pos += inc)
  761.     {
  762.       ptr = find (pos, *start, sizeof (unsigned short));
  763.       w = ptr ? *ptr : 0;
  764.       ptr = w ? make (pos + over, start, sizeof (unsigned short), buf) :
  765.         find (pos + over, *start, sizeof (unsigned short));
  766.       if (w || (ptr && *ptr))
  767.     *ptr = w;
  768.       if (pos == hi)
  769.     break;
  770.     }
  771.   for (pos = hi + over;;)
  772.     {
  773.       pos += inc;
  774.       ptr = find (pos, *start, sizeof (unsigned short));
  775.       if (ptr)
  776.     *ptr = 0;
  777.       if (pos == hi)
  778.     break;
  779.     }
  780. }
  781.  
  782. void 
  783. shift_widths (over, lo, hi)
  784.      int over;
  785.      CELLREF lo;
  786.      CELLREF hi;
  787. {
  788.   do_shift (over, lo, hi, &wids, COL_BUF);
  789. }
  790.  
  791.  
  792. /* Routines for dealing with the height of rows */
  793. #ifdef __STDC__
  794. unsigned short 
  795. get_height (CELLREF row)
  796. #else
  797. unsigned short 
  798. get_height (row)
  799.      CELLREF row;
  800. #endif
  801. {
  802.   unsigned short *ptr;
  803.  
  804.   ptr = find (row, hgts, sizeof (unsigned short));
  805.   if (!ptr || !*ptr)
  806.     return default_height;
  807.   return *ptr - 1;
  808. }
  809.  
  810. #ifdef __STDC__
  811. unsigned short 
  812. get_nodef_height (CELLREF row)
  813. #else
  814. unsigned short 
  815. get_nodef_height (row)
  816.      CELLREF row;
  817. #endif
  818. {
  819.   unsigned short *ptr;
  820.  
  821.   ptr = find (row, hgts, sizeof (unsigned short));
  822.   return ptr ? *ptr : 0;
  823. }
  824.  
  825. #ifdef __STDC__
  826. void 
  827. set_height (CELLREF row, unsigned short hgt)
  828. #else
  829. void 
  830. set_height (row, hgt)
  831.      CELLREF row;
  832.      unsigned short hgt;
  833. #endif
  834. {
  835.   unsigned short *ptr;
  836.  
  837.   ptr = make (row, &hgts, sizeof (unsigned short), ROW_BUF);
  838.   *ptr = hgt;
  839. }
  840.  
  841. int height_scale = 1;
  842. int width_scale = 1;
  843.  
  844. int 
  845. get_scaled_height (r)
  846.      CELLREF r;
  847. {
  848.   return get_height (r) * height_scale;
  849. }
  850.  
  851. int 
  852. get_scaled_width (c)
  853.      CELLREF c;
  854. {
  855.   return get_width (c) * width_scale;
  856. }
  857.  
  858.  
  859. #ifdef __STDC__
  860. void 
  861. find_heights (CELLREF lo, CELLREF hi)
  862. #else
  863. void 
  864. find_heights (lo, hi)
  865.      CELLREF lo;
  866.      CELLREF hi;
  867. #endif
  868. {
  869.   h_find = find_rng (&hgts, lo, hi, sizeof (unsigned short));
  870. }
  871.  
  872. #ifdef __STDC__
  873. unsigned short 
  874. next_height (CELLREF *posp)
  875. #else
  876. unsigned short 
  877. next_height (posp)
  878.      CELLREF *posp;
  879. #endif
  880. {
  881.   unsigned short *ptr;
  882.  
  883.   do
  884.     ptr = next_rng (h_find, posp);
  885.   while (ptr && !*ptr);
  886.   return ptr ? *ptr : 0;
  887. }
  888.  
  889. void 
  890. shift_heights (dn, lo, hi)
  891.      int dn;
  892.      CELLREF lo;
  893.      CELLREF hi;
  894. {
  895.   do_shift (dn, lo, hi, &hgts, ROW_BUF);
  896. }
  897.  
  898. #ifdef TEST
  899. extern char *bname[];
  900.  
  901. extern void dbg_print_ref_fm ();
  902. extern void dbg_print_ref_to ();
  903. extern void dbg_print_formula ();
  904.  
  905. void
  906. dbg_print_cell (cp)
  907.      CELL *cp;
  908. {
  909.   char *ptr1, *ptr2;
  910.   char tmpbuf[30];
  911.  
  912.   switch (GET_TYP (cp))
  913.     {
  914.     case 0:
  915.       ptr1 = "(null)";
  916.       ptr2 = "";
  917.       break;
  918.     case TYP_FLT:
  919.       sprintf (tmpbuf, "Float: %.16g", cp->cell_flt);
  920.       ptr1 = tmpbuf;
  921.       ptr2 = "";
  922.       break;
  923.     case TYP_INT:
  924.       sprintf (tmpbuf, "Int: %ld", cp->cell_int);
  925.       ptr1 = tmpbuf;
  926.       ptr2 = "";
  927.       break;
  928.     case TYP_ERR:
  929.       sprintf (tmpbuf, "Error: %d: ", cp->cell_err);
  930.       ptr1 = tmpbuf;
  931.       ptr2 = ename[cp->cell_err];
  932.       break;
  933.     case TYP_BOL:
  934.       sprintf (tmpbuf, "Bool: %d: ", cp->cell_bol);
  935.       ptr1 = tmpbuf;
  936.       ptr2 = bname[cp->cell_bol];
  937.       break;
  938.     case TYP_STR:
  939.       sprintf (tmpbuf, "String: %p: ", cp->cell_str);
  940.       ptr1 = tmpbuf;
  941.       ptr2 = cp->cell_str;
  942.       break;
  943.     default:
  944.       sprintf (tmpbuf, "Unknown: %d", GET_TYP (cp));
  945.       ptr1 = tmpbuf;
  946.       ptr2 = "";
  947.       break;
  948.     }
  949.   io_text_line ("    Cell %p:  flg %#lx  fm %p  to %p  fa %p  cy %d  val %s%s",
  950.         cp, cp->cell_flags, cp->cell_refs_from, cp->cell_refs_to,
  951.         cp->cell_formula, cp->cell_cycle, ptr1, ptr2);
  952.   dbg_print_ref_fm (cp->cell_refs_from);
  953.   dbg_print_ref_to (cp->cell_refs_to);
  954.   dbg_print_formula (cp->cell_formula);
  955. }
  956.  
  957. #ifdef __STDC__
  958. void 
  959. dbg_print_list (struct list *ptr, int ele, char *txt, void (*prsub) (void *))
  960. #else
  961. void 
  962. dbg_print_list (ptr, ele, txt, prsub)
  963.      struct list *ptr;
  964.      int ele;
  965.      char *txt;
  966.      void (*prsub) ();
  967. #endif
  968. {
  969.   CELLREF pos;
  970.  
  971.   while (ptr)
  972.     {
  973.       io_text_line ("%s %p: lo %u  hi %u  nxt %p  mem %p", txt, ptr, ptr->lo, ptr->hi, ptr->next, &(ptr->mem[0]));
  974.       pos = ptr->lo;
  975.       for (;;)
  976.     {
  977.       (*prsub) (ptr->mem + ele * (pos - ptr->lo));
  978.       if (pos == ptr->hi)
  979.         break;
  980.       pos++;
  981.     }
  982.       ptr = ptr->next;
  983.     }
  984. }
  985.  
  986. static void 
  987. dbg_pr_row (p)
  988.      VOIDSTAR p;
  989. {
  990.   io_text_line ("  %p", p);
  991. }
  992.  
  993. void 
  994. dbg_print_rows (pos)
  995.      CELLREF pos;
  996. {
  997.   dbg_print_list (the_cols, sizeof (struct list *), "row", dbg_pr_row);
  998. }
  999.  
  1000. static void 
  1001. dbg_pr_all (p)
  1002.      VOIDSTAR p;
  1003. {
  1004.   struct list **ptr;
  1005.  
  1006.   io_text_line ("  %p", p);
  1007.   ptr = p;
  1008.   dbg_print_list (*ptr, sizeof (struct cell), "  col",
  1009.             (void (*)(void *)) dbg_print_cell);
  1010. }
  1011.  
  1012. void 
  1013. dbg_print_array ()
  1014. {
  1015.   dbg_print_list (the_cols, sizeof (struct list *), "row", dbg_pr_all);
  1016. }
  1017.  
  1018. void 
  1019. dbg_print_cols (pos)
  1020.      CELLREF pos;
  1021. {
  1022.   /* struct list **ptr;
  1023.  
  1024.     ptr=find(...);
  1025.     if(...); */
  1026. }
  1027.  
  1028. #endif
  1029.  
  1030. #ifdef TEST_ME
  1031. main ()
  1032. {
  1033.   char buf[100];
  1034.   static void *vec[10];
  1035.   static siz[10];
  1036.   char *ret;
  1037.   int n;
  1038.   int t;
  1039.   int hi, lo;
  1040.   CELLREF pos;
  1041.   int z;
  1042.  
  1043.  
  1044.   while (printf ("-->"), gets (buf))
  1045.     {
  1046.       n = buf[1] - '0';
  1047.       switch (buf[0])
  1048.     {
  1049.     case 'i':
  1050.       if (sscanf (&buf[2], "%d %d", &siz[n], &t) < 1)
  1051.         {
  1052.           printf ("No size?\n");
  1053.           break;
  1054.         }
  1055.       vec[n] = list_init (siz[n], t);
  1056.       printf ("vec %d init'd to %lx with siz %u and buf %d\n", n, vec[n], siz[n], t);
  1057.       break;
  1058.  
  1059.     case 'f':
  1060.       ret = find (vec[n], atoi (&buf[2]));
  1061.       if (ret)
  1062.         {
  1063.           printf ("Found at %lx  ", ret);
  1064.           for (t = 0; t < siz[n]; t++)
  1065.         printf ("%x ", ret[t]);
  1066.           printf ("\n");
  1067.         }
  1068.       else
  1069.         printf ("Not found\n");
  1070.       break;
  1071.  
  1072.     case 'F':
  1073.       if (sscanf (&buf[2], "%d %d", &lo, &hi) != 2)
  1074.         {
  1075.           printf ("Faild to scan\n");
  1076.           break;
  1077.         }
  1078.       find_rng (vec[n], lo, hi);
  1079.       while (ret = next_rng (&pos))
  1080.         {
  1081.           printf ("Found %u at %lx  ", pos, ret);
  1082.           for (t = 0; t < siz[n]; t++)
  1083.         printf ("%x ", ret[t]);
  1084.           printf ("\n");
  1085.         }
  1086.       break;
  1087.  
  1088.     case 'm':
  1089.       ret = make (vec[n], atoi (&buf[2]));
  1090.       if (ret)
  1091.         {
  1092.           z = atoi (&buf[4]);
  1093.           printf ("Made at %lx  ", ret);
  1094.           for (t = 0; t < siz[n]; t++)
  1095.         {
  1096.           printf ("%x(%x) ", ret[t], z);
  1097.           ret[t] = z;
  1098.         }
  1099.           printf ("\n");
  1100.         }
  1101.       else
  1102.         printf ("Failed!!\n");
  1103.       break;
  1104.  
  1105.     case 'M':
  1106.       z = 0;
  1107.       if (sscanf (&buf[2], "%d %d %d", &lo, &hi, &z) < 2)
  1108.         {
  1109.           printf ("Scan failed\n");
  1110.           break;
  1111.         }
  1112.       make_rng (vec[n], lo, hi);
  1113.       while (ret = next_rng (&pos))
  1114.         {
  1115.           printf ("Found %u at %lx  ", pos, ret);
  1116.           for (t = 0; t < siz[n]; t++)
  1117.         {
  1118.           printf ("%x(%x) ", ret[t], z);
  1119.           ret[t] = z;
  1120.         }
  1121.           if (z)
  1122.         z++;
  1123.           printf ("\n");
  1124.         }
  1125.       break;
  1126.  
  1127.     case 'q':
  1128.       exit (0);
  1129.  
  1130.     default:
  1131.       printf ("Unknown command!\n");
  1132.     }
  1133.     }
  1134. }
  1135.  
  1136. #endif
  1137.